package com.example.locationreport.locationreport;

import android.Manifest;
import android.app.Activity;
import android.app.ActivityManager;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.os.Build;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.text.TextUtils;
import android.util.Log;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.ViewModel;
import androidx.lifecycle.ViewModelProvider;

import com.easysocket.EasySocket;
import com.easysocket.config.EasySocketOptions;
import com.easysocket.entity.OriginReadData;
import com.easysocket.entity.SocketAddress;
import com.easysocket.interfaces.conn.IConnectionManager;
import com.easysocket.interfaces.conn.ISocketActionListener;
import com.example.locationreport.locationreport.bean.CildXmlBean;
import com.example.locationreport.locationreport.bean.CommandMessageBean;
import com.example.locationreport.locationreport.db.Locations;
import com.example.locationreport.locationreport.bean.UpdateBean;
import com.example.locationreport.locationreport.bean.VehicleInfoBean;
import com.example.locationreport.locationreport.db.ReissueLocations;
import com.example.locationreport.locationreport.global.Constant;
import com.example.locationreport.locationreport.global.ConstantInfo;
import com.example.locationreport.locationreport.http.NetworkUtils;
import com.example.locationreport.locationreport.http.Url;
import com.example.locationreport.locationreport.http.network.OkGoBackListener;
import com.example.locationreport.locationreport.receiver.BatteryReceiver;
import com.example.locationreport.locationreport.receiver.CommonReceiver;
import com.example.locationreport.locationreport.service.DownAPKService;
import com.example.locationreport.locationreport.service.MqttService;
import com.example.locationreport.locationreport.utils.CommonUtils;
import com.example.locationreport.locationreport.utils.JsonUtils;
import com.example.locationreport.locationreport.utils.LogLocationUtils;
import com.example.locationreport.locationreport.utils.ReissueUtils;
import com.example.locationreport.locationreport.utils.XmlUtils;
import com.example.locationreport.locationreport.utils.voice.SpeakUtils;
import com.hjq.permissions.OnPermission;
import com.hjq.permissions.XXPermissions;

import org.litepal.LitePal;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

public class MainActivity extends AppCompatActivity {

    private static final String TAG = MainActivity.class.getSimpleName();

    public static Activity mActivity;

    // 是否已发送车辆信息
    private boolean isVersionSend = false;

    private IntentFilter mCommonIntentFilter; // 通用广播监听

    // 检查在线定位点数据的子线程
    private Thread mThreadOnline;

    // 检查在线其他数据的子线程
    private Thread mThreadOnlineOther;
    // 语音播放子线程
    private Thread mThreadSpeak;

    // 定时发送心跳请求
    private Thread mThreadHeartbeat;
    /*private Timer mTimerHeartbeat = new Timer();
    private TaskHeartbeat mTaskHeartbeat = new TaskHeartbeat();*/

    private Thread mOdbThreadHeartbeat;

    private TextView mTvSystemVersionCode,//系统版本号
            mTvSystemVersionName,//系统版本名
            mTvAppVersionCode,//应用版本号
            mTvAppVersionName;//应用版本名

    private Thread mReissueThread;
    //从文件读取到的需要上传的点位数据
    private ArrayList<String> rkinf_list = new ArrayList<>();
    //系统日志文件 过度集合
    private ArrayList<String> excessivelocationlist = new ArrayList<>();
    //系统日志文件集合
    private ArrayList<String> locationlist = new ArrayList<>();
    //最终需要读取的文件集合
    private ArrayList<String> fileslist = new ArrayList<>();
    //最终需要读取的文件集合索引
    private ArrayList<Integer> filesindexlist = new ArrayList<>();
    private Date startTimeDate;
    private Date endTimeDate;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        LogLocationUtils.writeLog(TAG, "MainActivity启动----------------------->：onCreate");
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mActivity = this;

        ActManager.getAppManager().addActivity(mActivity);


        if (savedInstanceState == null) {
            // 这是Activity首次创建时调用，只需执行一次初始化操作
            LogLocationUtils.writeLog(TAG, "这是Activity首次创建时调用，只需执行一次初始化操作");
            getActivityDataList();
            initView();
            initData();
        } else {
            // 这是由于配置更改导致的重新创建，不需要再次初始化
            LogLocationUtils.writeLog(TAG, "这是由于配置更改导致的重新创建，不需要再次初始化");
            ActManager.getAppManager().AppExit(mActivity);
        }
    }

    private void initView() {
        LogLocationUtils.writeLog(TAG, "MainActivity启动----------------------->：initView方法");
        mTvSystemVersionCode = findViewById(R.id.mTvSystemVersionCode);//系统版本号
        mTvSystemVersionName = findViewById(R.id.mTvSystemVersionName);//系统版本名
        mTvAppVersionCode = findViewById(R.id.mTvAppVersionCode);//应用版本号
        mTvAppVersionName = findViewById(R.id.mTvAppVersionName);//应用版本名
        LogLocationUtils.writeLog(TAG, "系统版本号:" + R.id.mTvSystemVersionCode + " 系统版本名:" + R.id.mTvSystemVersionName + " 应用版本号:" + R.id.mTvAppVersionCode + " 应用版本名:" + R.id.mTvAppVersionName);
        // 获取PackageManager实例
        PackageManager pm = getPackageManager();
        // 获取当前应用的包名
        String packageName = getPackageName();
        // 获取包信息，包含了版本信息等
        PackageInfo packageInfo = null;
        try {
            packageInfo = pm.getPackageInfo(packageName, 0);
        } catch (PackageManager.NameNotFoundException e) {
            throw new RuntimeException(e);
        }
        // 获取版本号
        int versionCode = packageInfo.versionCode;
        // 获取版本名称
        String versionName = packageInfo.versionName;
        // 输出版本信息

        LogLocationUtils.writeLog(TAG, "当前版本号:" + versionCode + " 当前版本名称:" + versionName);
        LogLocationUtils.writeLog(TAG, "初始化View完成...");
    }

    /**
     * 初始化数据
     */
    private void initData() {
        LogLocationUtils.writeLog(TAG, "MainActivity启动----------------------->：initData方法");
        CildXmlBean cildXmlBean = XmlUtils.readXml("/data/misc/cil/cild.xml");
        mTvSystemVersionCode.setText(CommonUtils.getNormalString(cildXmlBean.getSysVersion()));
        mTvSystemVersionName.setText(CommonUtils.getNormalString(cildXmlBean.getSysVersionName()));
        mTvAppVersionCode.setText(String.valueOf(CommonUtils.getVersionCode()));
        mTvAppVersionName.setText(CommonUtils.getVersionName());

        //初始化sqlite
        LitePal.initialize(mActivity);
        LitePal.getDatabase();

        // 检查更新数据
        getUpdateApp();

        // 开启接收定位点数据 mqtt 语音播报 电池广播
        initEasySocket();
        startMQTTServiceAndReceiver();
        startCommServiceAndReceiver();
        startBatteryServiceAndReceiver();

        // 获取权限，开启心跳机制
        getPermissionsInfo();
    }

    private void getActivityDataList() {
        PackageManager packageManager = getPackageManager();
        String packageName = getPackageName();
        try {
            PackageInfo packageInfo = packageManager.getPackageInfo(packageName, PackageManager.GET_ACTIVITIES);
            ActivityInfo[] activities = packageInfo.activities;
            if (activities != null) {
                for (ActivityInfo activityInfo : activities) {
                    LogLocationUtils.writeLog(TAG, "所有Activity---->" + activityInfo.name);
                }
            }
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
    }

    private void startMQTTServiceAndReceiver() {
        LogLocationUtils.writeLog(TAG, "MainActivity启动----------------------->：startMQTTService方法");
        try {
            //接收消息服务
            Intent mMqttService = new Intent(mActivity, MqttService.class);
            startService(mMqttService);
        } catch (Exception e) {
            LogLocationUtils.writeLog(TAG, "startMQTTService报错" + e.getMessage());
            e.printStackTrace();
            startMQTTServiceAndReceiver();
        }
    }

    private void startCommServiceAndReceiver() {
        LogLocationUtils.writeLog(TAG, "MainActivity启动----------------------->：startCommService方法");

        try {
            // 语音播报广播
            if (mCommonIntentFilter == null) {
                mCommonIntentFilter = new IntentFilter();
                mCommonIntentFilter.addAction(Constant.ReceiverSpeak);
                mCommonIntentFilter.addAction(Constant.ReceiverOnlineLocation);
                mCommonIntentFilter.addAction(Constant.CONFIGURATION_CHANGED);
                registerReceiver(mCommonReceiver, mCommonIntentFilter);
            }
        } catch (Exception e) {
            LogLocationUtils.writeLog(TAG, "startCommService报错" + e.getMessage());
            e.printStackTrace();
            startCommServiceAndReceiver();
        }
    }

    private void startBatteryServiceAndReceiver() {
        LogLocationUtils.writeLog(TAG, "MainActivity启动----------------------->：startBatteryService方法");
        try {
            //连接电池广播
            BatteryReceiver batteryReceiver = new BatteryReceiver();
            IntentFilter filter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
            registerReceiver(batteryReceiver, filter);
            LogLocationUtils.writeLog(TAG, "OdbLocationService服务及BatteryReceiver电池监听广播启动");
        } catch (Exception e) {
            LogLocationUtils.writeLog(TAG, "startBatteryService报错" + e.getMessage());
            e.printStackTrace();
            startBatteryServiceAndReceiver();
        }
    }

    /**
     * 获取权限
     */
    private void getPermissionsInfo() {
        XXPermissions.with(mActivity).permission(Manifest.permission.READ_PHONE_STATE,
                Manifest.permission.ACCESS_FINE_LOCATION,
                Manifest.permission.ACCESS_COARSE_LOCATION).request(new OnPermission() {
            @Override
            public void hasPermission(List<String> granted, boolean isAll) {
                // 定时发送心跳任务
                mThreadHeartbeat = new Thread(() -> {
                    heartbeatRunnable.run();
                });
                mThreadHeartbeat.setPriority(Thread.MIN_PRIORITY);
                mThreadHeartbeat.setName(Constant.MainHeartbeatThread);
                mThreadHeartbeat.start();


                //定时发送补发点位数据
                mReissueThread = new Thread(() -> {
                    mReissueRunnable.run();
                });
                mReissueThread.setPriority(Thread.MIN_PRIORITY);
                mReissueThread.setName(Constant.MainHeartbeatThread);
                mReissueThread.start();
            }

            @Override
            public void noPermission(List<String> denied, boolean quick) {
                LogLocationUtils.writeLog(TAG, "没权限执行逻辑");
            }
        });
    }

    /**
     * 定时上传心跳服务
     */
    private Runnable heartbeatRunnable = new Runnable() {
        //    private class TaskHeartbeat extends TimerTask {
        @Override
        public void run() {
            while (true) {
                if (ConstantInfo.VehicleInfoBean == null) {
                    // 获取车辆信息
                    getVehicleInfoByImei();
                } else {
                    // 发送车辆信息
                    sendVersionInfo();
                }
                try {
                    // 发送心跳请求
                    RabbitMQClient.getInstance().sendExchangeMessage(JsonUtils.parseBeanToJson(new CommandMessageBean(4)), Constant.ClientCommand);
                } catch (Exception e) {
                    LogLocationUtils.writeLog(TAG, e.getMessage());
                }

                // 检查离线点数据，如有提交
                setOfflineLocationData();

                try {
                    Thread.sleep(1000 * 15);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    };

    /**
     * 补发点位数据
     */
    private Runnable mReissueRunnable = new Runnable() {
        @Override
        public void run() {
            while (true) {
                //检查补充点数据，如有提交
                try {
                    setReissueLocationsData();
                } catch (Exception e) {
                    LogLocationUtils.writeLog(TAG, e.getMessage());
                }
                try {
                    Thread.sleep(1000 * 60 * 5);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    };

    private SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");

    /**
     * 检查离线点数据，如有提交
     */
    private void setOfflineLocationData() {
        if (CommonUtils.isConnectIsNormal()) {
            List<Locations> offlineLocationList = LitePal.order("TE").limit(200).find(Locations.class);

            if (offlineLocationList != null && offlineLocationList.size() > 0) {
                LogLocationUtils.writeLog(TAG, "网络正常，获取离线数据：" + offlineLocationList.size() + "条");
                for (int i = 0; i < offlineLocationList.size(); i++) {

                    offlineLocationList.get(i).setVehicleInfo(ConstantInfo.VehicleInfoBean);
                    offlineLocationList.get(i).setIsCache(1);
                    offlineLocationList.get(i).delete();

                    try {
                        if (null != offlineLocationList.get(i)) {
                            try {
                                offlineLocationList.get(i).setSendTime(simpleDateFormat.format(new Date()));
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        }
                        LogLocationUtils.writeLog(TAG, "location_离线:" + JsonUtils.parseBeanToJson(offlineLocationList.get(i)));
                        RabbitMQClient.getInstance().sendExchangeMessage(JsonUtils.parseBeanToJson(offlineLocationList.get(i)), Constant.ClientLocation);
                    } catch (Exception e) {
                        offlineLocationList.get(i).save();
                        LogLocationUtils.writeLog(TAG, "location_离线:" + e.getMessage());
                    }
                }
            } else {
                LogLocationUtils.writeLog(TAG, "location_离线:当前没有需要上传的离线点数据");
            }
        } else {
            LogLocationUtils.writeLog(TAG, "location_离线:" + (CommonUtils.isConnectIsNormal() ? "当前无网络" : "车辆数据为空不进行上传"));
        }
    }

    /**
     * 检查补充点数据，如有提交
     */
    private void setReissueLocationsData() {
        try {
            if (CommonUtils.isConnectIsNormal()) {
                //读取的系统日志数据 集合
                ArrayList<String> filepathlist = ReissueUtils.getReadSystemDirectory("/data/misc/cil/location");//location文件夹下所有文件
                //排序日志文件
                Collections.sort(filepathlist);
                excessivelocationlist.clear();
                fileslist.clear();
                locationlist.clear();
                for (String str : filepathlist) {
                    excessivelocationlist.add(str);
                }
                // 使用Collections.reverse()进行倒序
                Collections.reverse(excessivelocationlist);
                // 打印反转后的ArrayList
                for (String str2 : excessivelocationlist) {
                    locationlist.add(str2);
                }
                LogLocationUtils.writeLog(TAG, "ReissueLocations_补充点：系统日志location文件夹下所有文件名" + locationlist.toString());

                //读取数据库
                List<ReissueLocations> reissueLocationsList = LitePal.limit(200).find(ReissueLocations.class);
                if (reissueLocationsList.size() > 0) {
                    LogLocationUtils.writeLog(TAG, "ReissueLocations_补充点：数据库有" + reissueLocationsList.size() + "条数据");
                    for (int i = 0; i < reissueLocationsList.size(); i++) {
                        if (reissueLocationsList.get(i).getSEGMENTATION_TIME() != 0) {
                            String startTime = reissueLocationsList.get(i).getTE();//获取数据库开始时间
                            int segmentation_time = reissueLocationsList.get(i).getSEGMENTATION_TIME();//获取数据库间隔时间段
                            //相加开始时间和间隔时间 得结束时间
                            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                            Date date = null;
                            String endTime = null;
                            try {
                                date = dateFormat.parse(startTime);
                                date.setTime(date.getTime() + segmentation_time * 1000);
                                endTime = dateFormat.format(date);
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                            LogLocationUtils.writeLog(TAG, "ReissueLocations_补充点：开始时间：" + startTime + "----结束时间" + endTime);

                            try {
                                //开始时间
                                startTimeDate = dateFormat.parse(startTime);
                                //结束时间
                                endTimeDate = dateFormat.parse(endTime);
                            } catch (ParseException e) {
                                e.printStackTrace();
                            }

                            fileslist.clear();
                            filesindexlist.clear();
                            for (int j = 0; j < locationlist.size(); j++) {
                                //截取文件名后面的时间段
                                String userIdJiequ = locationlist.get(j).substring(locationlist.get(j).indexOf("_"));
                                String fileTime = ReissueUtils.getFileTime("location" + userIdJiequ);
                                if (fileTime != null) {
                                    boolean time = ReissueUtils.isTime(startTime, fileTime);
                                    if (time) {
                                        //存入开始时间
                                        fileslist.add(locationlist.get(j));
                                        filesindexlist.add(j);
                                        break;
                                    }
                                }
                            }

                            for (int j = 0; j < locationlist.size(); j++) {
                                //截取文件名后面的时间段
                                String userIdJiequ = locationlist.get(j).substring(locationlist.get(j).indexOf("_"));
                                String fileTime = ReissueUtils.getFileTime("location" + userIdJiequ);
                                if (fileTime != null) {
                                    boolean time = ReissueUtils.isTime(endTime, fileTime);
                                    if (time) {
                                        //存入结束时间
                                        fileslist.add(locationlist.get(j));
                                        filesindexlist.add(j);
                                        break;
                                    }
                                }
                            }

                            //开始根据获取的文件名称和路径读文件
                            if (fileslist.size() > 0) {
                                List<String> strings = locationlist.subList(filesindexlist.get(0), filesindexlist.get(1) + 1);
                                if (strings.size() > 0) {
                                    LogLocationUtils.writeLog(TAG, "ReissueLocations_补充点：需要读取的文件" + strings.toString());


                                    rkinf_list.clear();
                                    int number = 0;
                                    for (int l = 0; l < strings.size(); l++) {
                                        BufferedReader reader = null;
                                        try {
                                            Process process = Runtime.getRuntime().exec("chmod 777 " + strings.get(l));
                                            File logFile = new File(strings.get(l));
                                            reader = new BufferedReader(new FileReader(logFile));
                                            String line;
                                            while ((line = reader.readLine()) != null) {
                                                if (line.contains("$RKINF")) {
                                                    String[] location = line.split(",");
                                                    Date rkinfDdate = ReissueUtils.getRKINFDdate(location);
                                                    if (rkinfDdate.getTime() >= startTimeDate.getTime() && rkinfDdate.getTime() <= endTimeDate.getTime()) {
                                                        rkinf_list.add(line);
                                                        if (rkinfDdate.getTime() == endTimeDate.getTime()) {
                                                            if (reader != null) {
                                                                try {
                                                                    reader.close();
                                                                } catch (IOException e) {
                                                                    e.printStackTrace();
                                                                }
                                                            }
                                                        }

                                                    } else if (rkinfDdate.getTime() > endTimeDate.getTime()) {
                                                        if (reader != null) {
                                                            try {
                                                                reader.close();
                                                            } catch (IOException e) {
                                                                e.printStackTrace();
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                            number++;
                                            LogLocationUtils.writeLog(TAG, "ReissueLocations_补充点：读取正确" + strings.get(l));
                                        } catch (IOException e) {
                                            LogLocationUtils.writeLog(TAG, "ReissueLocations_补充点：读取错误" + e.getMessage());
                                            e.printStackTrace();
                                        } finally {
                                            if (reader != null) {
                                                try {
                                                    reader.close();
                                                } catch (IOException e) {
                                                    e.printStackTrace();
                                                }
                                            }
                                        }
                                    }

                                    try {
                                        if (rkinf_list.size() == 0 && number == rkinf_list.size()) {
                                            LitePal.delete(ReissueLocations.class, reissueLocationsList.get(i).getId());
                                        }
                                    } catch (Exception e) {
                                        LogLocationUtils.writeLog(TAG, "ReissueLocations_补充点：" + e.getMessage());
                                    }

                                }
                            }

                            //开始进行点位数据补发
                            if (rkinf_list != null) {
                                if (CommonUtils.isConnectIsNormal()) {
                                    int rkinf = 0;
                                    boolean isrkinf = false;
                                    if (rkinf_list != null && rkinf_list.size() > 0) {
                                        LogLocationUtils.writeLog(TAG, "ReissueLocations_补充点：网络正常，获取补发点位数据" + rkinf_list.size() + "条");
                                        isrkinf = true;
                                        for (int y = 0; y < rkinf_list.size(); y++) {
                                            Locations locations = null;
                                            int colonIndex = rkinf_list.get(y).indexOf(":");
                                            if (colonIndex != -1) {
                                                String RKINF = rkinf_list.get(y).substring(colonIndex + 1);
                                                locations = new Locations(RKINF);
                                            }
                                            if (locations != null) {
                                                try {
                                                    locations.setIsCache(1);
                                                    LogLocationUtils.writeLog(TAG, "ReissueLocations_补充点: " + JsonUtils.parseBeanToJson(locations));
                                                    RabbitMQClient.getInstance().sendExchangeMessage(JsonUtils.parseBeanToJson(locations), Constant.ClientLocation);
                                                    rkinf++;
                                                } catch (Exception e) {
                                                    LogLocationUtils.writeLog(TAG, "ReissueLocations_补充点: 上传失败原因-" + e.getMessage());
                                                    break;
                                                }
                                            }
                                        }
                                    } else {
                                        LogLocationUtils.writeLog(TAG, "ReissueLocations_补充点: 当前没有需要上传的补发点数据");
                                    }
                                    //根据上传成功是否结果判断进行删除数据库
                                    if (rkinf_list.size() == rkinf && isrkinf == true) {
                                        LitePal.delete(ReissueLocations.class, reissueLocationsList.get(i).getId());
                                        isrkinf = false;
                                        LogLocationUtils.writeLog(TAG, "ReissueLocations_补充点: 全部补发成功,已删除相应数据");
                                    } else {
                                        LogLocationUtils.writeLog(TAG, "ReissueLocations_补充点: 没能全部补发成功,不进行删除库操作");
                                    }
                                } else {
                                    LogLocationUtils.writeLog(TAG, "ReissueLocations_补充点: 当前无网络");
                                }
                            }
                        } else {
                            LogLocationUtils.writeLog(TAG, "ReissueLocations_补充点: 补充点位为空不进行上传：SEGMENTATION_TIME=0");
                        }
                    }
                } else {
                    LogLocationUtils.writeLog(TAG, "ReissueLocations_补充点: 补充点位为空不进行上传");
                }
            } else {
                LogLocationUtils.writeLog(TAG, "ReissueLocations_补充点: 当前无网络");
            }
        } catch (Exception e) {
            LogLocationUtils.writeLog(TAG, "ReissueLocations_补充点: " + e.getMessage());
        }
    }

    /**
     * 获取车辆信息
     */
    private void getVehicleInfoByImei() {
        NetworkUtils.getVehicleInfoByImei(new OkGoBackListener(Url.vehicleInfoByImei) {
            @Override
            public void onSuccess(Object body) {
                ConstantInfo.VehicleInfoBean = (VehicleInfoBean) body;

                LogLocationUtils.writeLog(TAG, "车辆信息:" + JsonUtils.parseBeanToJson(ConstantInfo.VehicleInfoBean));
            }
        });
    }

    /**
     * 发送版本信息
     */
    private void sendVersionInfo() {
        // 已发送车辆信息
        if (isVersionSend)
            return;

        try {
            // 发送版本信息
            isVersionSend = true;
            RabbitMQClient.getInstance().sendExchangeMessage(JsonUtils.parseBeanToJson(new CommandMessageBean(2, new CommandMessageBean.MessageBody())), Constant.ClientCommand);
        } catch (Exception e) {
            isVersionSend = false;
            LogLocationUtils.writeLog(TAG, e.getMessage());
        }
    }

    /**
     * 获取更新
     */
    private void getUpdateApp() {
        LogLocationUtils.writeLog(TAG, "--UpdateApp: 请求更新版本接口--");

        if (!CommonUtils.isConnectIsNormal()) {
            LogLocationUtils.writeLog(TAG, "--UpdateApp: 当前没网络--");
        }

        NetworkUtils.getUpdateAppInfo(new OkGoBackListener(Url.updateApp) {
            @Override
            public void onSuccess(Object body) {
                LogLocationUtils.writeLog(TAG, "--UpdateApp: 请求更新版本接口成功--");

                UpdateBean updateBean = (UpdateBean) body;

                try {
                    if (Integer.parseInt(updateBean.getPackVersion()) > CommonUtils.getVersionCode()) {
                        LogLocationUtils.writeLog(TAG, "--UpdateApp: apk需要更新--");
                        initApkDownload(updateBean);
                    } else {
                        LogLocationUtils.writeLog(TAG, "--UpdateApp: apk不需要更新--");
                    }
                } catch (Exception e) {
                    LogLocationUtils.writeLog(TAG, "--UpdateApp：packVersion转换异常--:" + JsonUtils.parseBeanToJson(updateBean));
                }
            }
        });
    }

    /**
     * 判断是否能下载
     *
     * @param updateBean
     */
    private void initApkDownload(UpdateBean updateBean) {
        LogLocationUtils.writeLog(TAG, "--UpdateApp: 需要更新版本--");

        if (!XXPermissions.isHasPermission(mActivity, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
            LogLocationUtils.writeLog(TAG, "--UpdateApp: 无权限，需要请求--");
            XXPermissions.with(mActivity)
                    .constantRequest()
                    .permission(Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE)
                    .request(new OnPermission() {
                        @Override
                        public void hasPermission(List<String> granted, boolean isAll) {
                            startServiceDownload(updateBean);
                        }

                        @Override
                        public void noPermission(List<String> denied, boolean quick) {
                        }
                    });
        } else {
            LogLocationUtils.writeLog(TAG, "--UpdateApp: 有权限--");

            startServiceDownload(updateBean);
        }
    }

    /**
     * 开启下载服务
     *
     * @param updateBean
     */
    private void startServiceDownload(UpdateBean updateBean) {
        LogLocationUtils.writeLog(TAG, "--UpdateApp: 开始更新--");

        Intent intent = new Intent(mActivity, DownAPKService.class);
        Bundle bundle = new Bundle();
        bundle.putSerializable(Constant.INFO, updateBean);
        intent.putExtras(bundle);
        startService(intent);
    }

    /**
     * 监听消息广播
     */
    protected CommonReceiver mCommonReceiver = new CommonReceiver() {
        @Override
        public void initSpeak() {
            LogLocationUtils.writeLog(TAG, "接收播放语音广播:" + ConstantInfo.IsMQTTSpeaking);

            // 已有消息播报中
            if (ConstantInfo.IsMQTTSpeaking)
                return;

            ConstantInfo.IsMQTTSpeaking = true;

            mThreadSpeak = new Thread(() -> {
                mSpeakRunnable.run();
            });
            mThreadSpeak.setPriority(Thread.MAX_PRIORITY);
            mThreadSpeak.setName(Constant.SpeakPlayThread);
            mThreadSpeak.start();
        }

        @Override
        public void initOnlineLocation() {
            LogLocationUtils.writeLog(TAG, "接收上传在线定位点广播:" + ConstantInfo.IsOnlineLocationUploading);

            // 已有消息上传中
            if (ConstantInfo.IsOnlineLocationUploading)
                return;

            ConstantInfo.IsOnlineLocationUploading = true;

            // 开启子线程，上传在线定位点
            mThreadOnline = new Thread(() -> {
                onlineLocationRunnable.run();
            });
            mThreadOnline.setPriority(Thread.MAX_PRIORITY);
            mThreadOnline.setName(Constant.OnlineLocationThread);
            mThreadOnline.start();
        }

        @Override
        public void initOnlineOther() {
            LogLocationUtils.writeLog(TAG, "接收上传在线其他信息广播:" + ConstantInfo.IsOnlineOtherUploading);

            // 已有消息上传中
            if (ConstantInfo.IsOnlineOtherUploading)
                return;

            ConstantInfo.IsOnlineOtherUploading = true;

            // 开启子线程，上传在线其他数据
            mThreadOnlineOther = new Thread(() -> {
                onlineOtherRunnable.run();
            });
            mThreadOnlineOther.setPriority(Thread.MAX_PRIORITY);
            mThreadOnlineOther.setName(Constant.OnlineOtherThread);
            mThreadOnlineOther.start();
        }

        @Override
        public void initActivityMethod() {
            LogLocationUtils.writeLog(TAG, "已接收到：android.intent.action.CONFIGURATION_CHANGED 广播");
            LogLocationUtils.writeLog(TAG, "已执行 System.exit(0) 方法");
            android.os.Process.killProcess(android.os.Process.myPid());
            System.exit(0);
        }
    };

    /**
     * 在线数据发送
     */
    private Runnable onlineLocationRunnable = new Runnable() {
        @Override
        public void run() {
            while (true) {
                if (!CommonUtils.isConnectIsNormal()) {
                    LogLocationUtils.writeLog(TAG, "location_在线:当前无网络");
                    ConstantInfo.IsOnlineLocationUploading = false;
                    break;
                }

                if (ConstantInfo.OnlineLocationLinkedList == null
                        || ConstantInfo.OnlineLocationLinkedList.size() < 1) {
                    LogLocationUtils.writeLog(TAG, "location_在线:当前无数据");
                    ConstantInfo.IsOnlineLocationUploading = false;
                    break;
                }

                // 无线轮询在线定位点数据存储集合
                Locations locations = ConstantInfo.OnlineLocationLinkedList.poll();
                if (null != locations) {
                    try {
                        locations.setSendTime(simpleDateFormat.format(new Date()));
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    LogLocationUtils.writeLog(TAG, "location_在线:" + JsonUtils.parseBeanToJson(locations));
                }
                try {
                    RabbitMQClient.getInstance().sendExchangeMessage(JsonUtils.parseBeanToJson(locations), Constant.ClientLocation);
                } catch (Exception e) {
                    LogLocationUtils.writeLog(TAG, "location_在线发送失败:" + e.getMessage());
                }
            }
        }
    };

    /**
     * 在线数据发送
     */
    private Runnable mSpeakRunnable = new Runnable() {
        @Override
        public void run() {
            while (true) {
                LogLocationUtils.writeLog(TAG, "播报语音消息:" + ConstantInfo.MQTTQueue.size());

                // 无线轮询在线定位点数据存储集合
                if (ConstantInfo.MQTTQueue == null
                        || ConstantInfo.MQTTQueue.size() < 1) {

                    LogLocationUtils.writeLog(TAG, "播放语音完成:当前无数据");

                    ConstantInfo.IsMQTTSpeaking = false;
                    break;
                }

                try {
                    String mqttMessage = ConstantInfo.MQTTQueue.takeFirst();
                    SpeakUtils.getInstance().play(mqttMessage);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    LogLocationUtils.writeLog(TAG, "获取语音消息失败:" + e.getMessage());
                }

                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    };

    /**
     * 在线数据发送
     */
    private Runnable onlineOtherRunnable = new Runnable() {
        @Override
        public void run() {
            while (true) {
                if (!CommonUtils.isConnectIsNormal()) {
                    LogLocationUtils.writeLog(TAG, "other_在线:当前无网络");
                    ConstantInfo.IsOnlineOtherUploading = false;
                    break;
                }

                if (ConstantInfo.OnlineOtherLinkedList == null
                        || ConstantInfo.OnlineOtherLinkedList.size() < 1) {
                    LogLocationUtils.writeLog(TAG, "other_在线:当前无数据");
                    ConstantInfo.IsOnlineOtherUploading = false;
                    break;
                }

                // 无线轮询在线其他数据存储集合
                String info = ConstantInfo.OnlineOtherLinkedList.poll();
                LogLocationUtils.writeLog(TAG, "other_在线:" + info);
                try {
                    RabbitMQClient.getInstance().sendExchangeMessage(info, Constant.ClientOther);
                } catch (Exception e) {
                    LogLocationUtils.writeLog(TAG, "other_在线发送失败:" + e.getMessage());
                }

                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    };

    private Boolean checkRun = true;

    /**
     * 初始化EasySocket
     */
    private void initEasySocket() {
        try {
            //socket配置
            EasySocketOptions options = new EasySocketOptions.Builder()
                    .setSocketAddress(new SocketAddress(Constant.Odb_Location_Address, Constant.Odb_Location_Port)) //主机地址
                    .build();
            //初始化EasySocket
            EasySocket.getInstance().createConnection(options, CrashApplication.getContext());
            //监听
            EasySocket.getInstance().subscribeSocketAction(socketActionListener, Constant.Odb_Location_Address + ":" + Constant.Odb_Location_Port);
            LogLocationUtils.writeLog(TAG, "--OdbServiceServiceSocket初始化easySocket成功");

            // 定时发送心跳任务
//            if (null == mOdbThreadHeartbeat) {
//                mOdbThreadHeartbeat = new Thread(() -> {
//                    odbHeartbeatRunnable.run();
//                });
//                mOdbThreadHeartbeat.setPriority(Thread.MIN_PRIORITY);
//                mOdbThreadHeartbeat.setName(Constant.ODBHeartbeatThread);
//                mOdbThreadHeartbeat.start();
//            }
        } catch (Exception e) {
            while (true) {
                try {
                    if (null != EasySocket.getInstance() || !EasySocket.getInstance().getConnection(Constant.Odb_Location_Address + ":" + Constant.Odb_Location_Port).isConnectViable()) {
                        break;
                    }
                } finally {
                    LogLocationUtils.writeLog(TAG, "初始化未完成easySocket...");
                    try {
                        Thread.sleep(1000 * 1);
                    } catch (InterruptedException interruptedException) {
                        interruptedException.printStackTrace();
                    }
                }
            }
            LogLocationUtils.writeLog(TAG, "--OdbServiceServiceSocket初始化easySocket失败");
        }
    }

    /**
     * socket行为监听
     */
    private ISocketActionListener socketActionListener = new ISocketActionListener() {

        /**
         * socket连接成功
         * @param socketAddress
         */
        public void onSocketConnSuccess(SocketAddress socketAddress) {
            LogLocationUtils.writeLog(TAG, "--OdbServiceServiceSocket连接成功:" + socketAddress.getPort());
        }

        /**
         * socket连接失败
         * @param socketAddress
         * @param isNeedReconnect 是否需要重连
         */
        public void onSocketConnFail(SocketAddress socketAddress, boolean isNeedReconnect) {
            LogLocationUtils.writeLog(TAG, "--OdbServiceServiceSocket连接失败:" + socketAddress.getPort());
            ActManager.getAppManager().AppExit(mActivity);
        }

        /**
         * 断开socket连接
         * @param socketAddress
         * @param isNeedReconnect 是否需要重连
         */
        public void onSocketDisconnect(SocketAddress socketAddress, boolean isNeedReconnect) {
            LogLocationUtils.writeLog(TAG, "--OdbServiceServiceSocket断开连接:" + socketAddress.getPort());
            ActManager.getAppManager().AppExit(mActivity);
        }

        /**
         * socket数据响应
         * @param socketAddress
         * @param originReadData
         */
        public void onSocketResponse(SocketAddress socketAddress, OriginReadData originReadData) {

        }

        /**
         * socket数据响应
         * @param socketAddress
         * @param readData
         */
        public void onSocketResponse(SocketAddress socketAddress, String readData) {
            try {
                LogLocationUtils.writeLog(TAG, "--OdbServiceServiceSocket方法2数据响应:" + socketAddress.getPort() + "..." + readData);
                if (null != readData && !readData.isEmpty()) {
                    String[] dealData = readData.split("\r\n");
                    for (String item : dealData) {
                        if (!TextUtils.isEmpty(item) && item.contains(Constant.RK_INF)) {
                            initLocations(item);
                        } else if (!TextUtils.isEmpty(item) && item.contains(Constant.RTK_FIX)) {
                            initRtkFix(item);
                        } else {
                            LogLocationUtils.writeLog(TAG, "--OdbServiceServiceSocket方法2处理其他数据，不予处理");
                        }
                    }
                } else {
                    LogLocationUtils.writeLog(TAG, "--OdbServiceServiceSocket方法2处理其他数据，不予处理");
                }
            } catch (Exception e) {
                LogLocationUtils.writeLog(TAG, "--OdbServiceServiceSocket方法2错误:" + socketAddress.getPort() + "..." + e.getMessage());
            } finally {
                checkRun = true;
            }
            LogLocationUtils.writeLog(TAG, "--OdbServiceServiceSocket方法2处理完成");
        }

        /**
         * socket数据响应
         * @param socketAddress
         * @param readData
         */
        public void onSocketResponse(SocketAddress socketAddress, byte[] readData) {

        }
    };

    /**
     * 初始化定位点数据
     *
     * @param readData
     */
    private void initLocations(String readData) {
        try {
            Locations locations = new Locations(readData, ConstantInfo.VehicleInfoBean);
            if (ConstantInfo.OnlineLocationLinkedList == null)
                ConstantInfo.OnlineLocationLinkedList = new LinkedList<>();

            if (CommonUtils.isConnectIsNormal()) {

                if (ConstantInfo.OnlineLocationLinkedList.size() < 60)
                    ConstantInfo.OnlineLocationLinkedList.add(locations);

                // 发送在线定位数据需要上传广播
                sendOnlineLocationReceiver();
            } else {
                locations.setIsCache(1);
                locations.save();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 初始化rtkFix数据
     *
     * @param readData
     */
    private void initRtkFix(String readData) {

        if (ConstantInfo.OnlineOtherLinkedList == null)
            ConstantInfo.OnlineOtherLinkedList = new LinkedList<>();

        if (CommonUtils.isConnectIsNormal()) {

            if (ConstantInfo.OnlineOtherLinkedList.size() < 60)
                ConstantInfo.OnlineOtherLinkedList.add(readData);

            // 发送在线其他数据需要上传广播
            sendOtherReceiver();
        }
    }

    /**
     * 发送播放语音广播
     *
     * @param type
     */
    private Intent mOnlineLocationReceiverIntent;

    private void sendOnlineLocationReceiver() {
        if (ConstantInfo.OnlineLocationLinkedList == null
                || ConstantInfo.OnlineLocationLinkedList.size() < 1
                || ConstantInfo.IsOnlineLocationUploading)
            return;

        if (mOnlineLocationReceiverIntent == null) {
            mOnlineLocationReceiverIntent = new Intent(Constant.ReceiverOnlineLocation);
            mOnlineLocationReceiverIntent.putExtra(Constant.TYPE, Constant.RK_INF);
        } else {
            mOnlineLocationReceiverIntent.putExtra(Constant.TYPE, Constant.RK_INF);
        }

        sendBroadcast(mOnlineLocationReceiverIntent);
    }

    private void sendOtherReceiver() {
        if (ConstantInfo.OnlineOtherLinkedList == null
                || ConstantInfo.OnlineOtherLinkedList.size() < 1
                || ConstantInfo.IsOnlineOtherUploading)
            return;

        if (mOnlineLocationReceiverIntent == null) {
            mOnlineLocationReceiverIntent = new Intent(Constant.ReceiverOnlineLocation);
            mOnlineLocationReceiverIntent.putExtra(Constant.TYPE, Constant.OTHER_INF);
        } else {
            mOnlineLocationReceiverIntent.putExtra(Constant.TYPE, Constant.OTHER_INF);
        }

        sendBroadcast(mOnlineLocationReceiverIntent);
    }

    /**
     * 定时上传心跳服务
     */
    private Runnable odbHeartbeatRunnable = new Runnable() {
        //    private class TaskHeartbeat extends TimerTask {
        @Override
        public void run() {
            while (true) {
                LogLocationUtils.writeLog(TAG, "运行3秒心跳检测");
                if (!checkRun) {
                    LogLocationUtils.writeLog(TAG, "进行修复easySocket...");
                    try {
                        EasySocket easySocket = EasySocket.getInstance();
                        if (null != easySocket) {
                            IConnectionManager iConnectionManager = easySocket.getConnection(Constant.Odb_Location_Address + ":" + Constant.Odb_Location_Port);
                            if (null != iConnectionManager) {
                                easySocket.disconnect(false);
                                easySocket.destroyConnection(Constant.Odb_Location_Address + ":" + Constant.Odb_Location_Port);
                            }
                        }
                        initEasySocket();
                        LogLocationUtils.writeLog(TAG, "判断初始化是否完成easySocket...");
                        while (true) {
                            try {
                                if (null != easySocket || !easySocket.getConnection(Constant.Odb_Location_Address + ":" + Constant.Odb_Location_Port).isConnectViable()) {
                                    break;
                                }
                            } finally {
                                LogLocationUtils.writeLog(TAG, "初始化未完成easySocket...");
                                Thread.sleep(1000 * 1);
                            }
                        }
                        LogLocationUtils.writeLog(TAG, "初始化完成easySocket...");
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                checkRun = false;
                try {
                    Thread.sleep(1000 * 3);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    };

    @Override
    protected void onResume() {
        super.onResume();
        LogLocationUtils.writeLog(TAG, "MainActivity启动----------------------->：onResume方法");
    }

    @Override
    protected void onRestart() {
        super.onRestart();
        LogLocationUtils.writeLog(TAG, "MainActivity启动----------------------->：onRestart方法");
    }

    @Override
    protected void onStart() {
        super.onStart();
        LogLocationUtils.writeLog(TAG, "MainActivity启动----------------------->：onStart方法");
    }

    @Override
    protected void onStop() {
        super.onStop();
        LogLocationUtils.writeLog(TAG, "MainActivity启动----------------------->：onStop方法");
    }

    @Override
    protected void onPause() {
        super.onPause();
        LogLocationUtils.writeLog(TAG, "MainActivity启动----------------------->：onPause方法");
    }

    @Override
    protected void onDestroy() {
        LogLocationUtils.writeLog(TAG, "MainActivity启动----------------------->：onDestroy方法");
        try {
            if (mOdbThreadHeartbeat != null)
                LogLocationUtils.writeLog(TAG, "MainActivity启动----------------------->：mOdbThreadHeartbeat.interrupt()");
            mOdbThreadHeartbeat.interrupt();
        } catch (Exception e) {
            e.printStackTrace();
        }

        try {
            LogLocationUtils.writeLog(TAG, "MainActivity启动----------------------->：CommonUtils.stopService(\"MqttService\")");
            CommonUtils.stopService("MqttService");
        } catch (Exception e) {
            e.printStackTrace();
        }

        try {
            if (EasySocket.getInstance() != null) {
                LogLocationUtils.writeLog(TAG, "MainActivity启动----------------------->：easySocket.disconnect(false)");
                EasySocket.getInstance().disconnect(false);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        /*if (mTimerHeartbeat != null) {
            mTimerHeartbeat.cancel();
            mTimerHeartbeat = null;
        }

        if (mTaskHeartbeat != null) {
            mTaskHeartbeat.cancel();
            mTaskHeartbeat = null;
        }*/

        /*try {
            if (mThreadOnline != null)
                mThreadOnline.interrupt();
        } catch (Exception e) {
            e.printStackTrace();
        }

        try {
            if (mThreadSpeak != null)
                mThreadSpeak.interrupt();
        } catch (Exception e) {
            e.printStackTrace();
        }

        try {
            if (mThreadOnlineOther != null)
                mThreadOnlineOther.interrupt();
        } catch (Exception e) {
            e.printStackTrace();
        }

        try {
            if (mThreadHeartbeat != null)
                mThreadHeartbeat.interrupt();
        } catch (Exception e) {
            e.printStackTrace();
        }

         */
        super.onDestroy();
    }

    @Override
    public void onConfigurationChanged(@NonNull Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        LogLocationUtils.writeLog(TAG, "启动: onConfigurationChanged");
    }

}
